﻿using Gadgeteer.Interfaces.Timed;
using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace Gadgeteer.Interfaces.Fakes.Tests
{
    [TestFixture]
    public class ThreadingTimerFactoryTest
    {
        [Test]
        public void DueInAndAFewTicks()
        {
            ITimerFactory factory = new ThreadingTimerFactory();
            var timer = factory.Create(20, 50, TimerBehavior.RunContinuously);

            int tickCount = 0;
            timer.Tick += t => tickCount++;
            timer.Start();
            Assert.That(tickCount, Is.EqualTo(0));

            Thread.Sleep(40);
            Assert.That(tickCount, Is.EqualTo(1));

            Thread.Sleep(70);
            Assert.That(tickCount, Is.EqualTo(2));

            timer.Stop();
            Thread.Sleep(50);
            Assert.That(tickCount, Is.EqualTo(2));
        }

        [Test]
        public void DirectlyAFewTicks()
        {
            ITimerFactory factory = new ThreadingTimerFactory();
            var timer = factory.Create(50, TimerBehavior.RunContinuously);

            int tickCount = 0;
            timer.Tick += t => tickCount++;
            timer.Start();
            Assert.That(tickCount, Is.EqualTo(0));

            Thread.Sleep(60);
            Assert.That(tickCount, Is.EqualTo(1));

            Thread.Sleep(70);
            Assert.That(tickCount, Is.EqualTo(2));

            timer.Stop();
            Thread.Sleep(70);
            Assert.That(tickCount, Is.EqualTo(2));
        }

        [Test]
        public void RunOnce_DueIn()
        {
            ITimerFactory factory = new ThreadingTimerFactory();
            var timer = factory.Create(25, 50, TimerBehavior.RunOnce);

            int tickCount = 0;
            timer.Tick += t => tickCount++;
            timer.Start();
            Assert.That(tickCount, Is.EqualTo(0));

            Thread.Sleep(49);
            Assert.That(tickCount, Is.EqualTo(0));

            Thread.Sleep(50);
            Assert.That(tickCount, Is.EqualTo(1));
            Thread.Sleep(50);
            Assert.That(tickCount, Is.EqualTo(1));

            timer.Stop();
            Thread.Sleep(50);
            Assert.That(tickCount, Is.EqualTo(1));
        }
    }
}
